package com.ck.serviceImpl;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import com.ck.dao.ExamBanjiDAO;
import com.ck.dao.ExamDAO;
import com.ck.dao.PanduanDAO;
import com.ck.dao.PaperDAO;
import com.ck.dao.StudentDAO;
import com.ck.dao.StudentExamDAO;
import com.ck.dao.StudentPaperDAO;
import com.ck.dao.TiankongDAO;
import com.ck.dao.WrongPanduanDAO;
import com.ck.dao.WrongTiankongDAO;
import com.ck.dao.WrongXuanzeDAO;
import com.ck.dao.XuanzeDAO;
import com.ck.domain.Exam;
import com.ck.domain.ExamBanji;
import com.ck.domain.Panduan;
import com.ck.domain.Paper;
import com.ck.domain.StudentExam;
import com.ck.domain.StudentPaper;
import com.ck.domain.Tiankong;
import com.ck.domain.WrongPanduan;
import com.ck.domain.WrongTiankong;
import com.ck.domain.WrongXuanze;
import com.ck.domain.Xuanze;
import com.ck.service.ExamService;

public class ExamServiceImpl implements ExamService {
	
	private ExamDAO examDAO;
	private ExamBanjiDAO examBanjiDAO;
	private StudentExamDAO studentExamDAO;
	private StudentPaperDAO studentPaperDAO;
	private StudentDAO studentDAO;
	private PanduanDAO panduanDAO;
	private XuanzeDAO xuanzeDAO;
	private TiankongDAO tiankongDAO;
	private PaperDAO paperDAO;
	private WrongPanduanDAO wrongPanduanDAO;
	private WrongXuanzeDAO wrongXuanzeDAO;
	private WrongTiankongDAO wrongTiankongDAO;
	
	private ExamBanji examBanji;
	private StudentExam studentExam;

	public void setExamDAO(ExamDAO examDAO) {
		this.examDAO = examDAO;
	}

	public void setExamBanjiDAO(ExamBanjiDAO examBanjiDAO) {
		this.examBanjiDAO = examBanjiDAO;
	}

	public void setStudentExamDAO(StudentExamDAO studentExamDAO) {
		this.studentExamDAO = studentExamDAO;
	}

	public void setStudentPaperDAO(StudentPaperDAO studentPaperDAO) {
		this.studentPaperDAO = studentPaperDAO;
	}

	public void setStudentDAO(StudentDAO studentDAO) {
		this.studentDAO = studentDAO;
	}

	public void setPanduanDAO(PanduanDAO panduanDAO) {
		this.panduanDAO = panduanDAO;
	}

	public void setXuanzeDAO(XuanzeDAO xuanzeDAO) {
		this.xuanzeDAO = xuanzeDAO;
	}

	public void setTiankongDAO(TiankongDAO tiankongDAO) {
		this.tiankongDAO = tiankongDAO;
	}

	public void setPaperDAO(PaperDAO paperDAO) {
		this.paperDAO = paperDAO;
	}

	public void setExamBanji(ExamBanji examBanji) {
		this.examBanji = examBanji;
	}

	public void setStudentExam(StudentExam studentExam) {
		this.studentExam = studentExam;
	}
	
	public void setWrongPanduanDAO(WrongPanduanDAO wrongPanduanDAO) {
		this.wrongPanduanDAO = wrongPanduanDAO;
	}

	public void setWrongXuanzeDAO(WrongXuanzeDAO wrongXuanzeDAO) {
		this.wrongXuanzeDAO = wrongXuanzeDAO;
	}

	public void setWrongTiankongDAO(WrongTiankongDAO wrongTiankongDAO) {
		this.wrongTiankongDAO = wrongTiankongDAO;
	}

	public Exam gainExam(Integer id) {
		return examDAO.getExamById(id);
	}
	
	public List<Exam> gainUnstartExamList() {
		return examDAO.getAllUnstartExam();
	}
	
	public List<Exam> gainOnGoingExamList(){
		return examDAO.getAllOnGoingExam();
	}
	
	public List<Exam> gainFinishedExamList(){
		return examDAO.getAllFinishedExam();
	}

	public List<ExamBanji> gainBanjiListForExam(Integer exam) {
		return examBanjiDAO.getBanjiListForExam(exam);
	}

	public Exam gainUnstartExam(Integer id) {
		return examDAO.getUnstartExamById(id);
	}

	public boolean addNewExam(Exam exam, String[] banji_array, Map model) {
		try {
			Date now = new Date();
			
			//这一段需要用事务！！！
			//预处理exam信息
			exam.setCst_create(now);
			exam.setCst_modify(now);
			exam.setStatus(1);
			//添加考试信息
			examDAO.addNewExam(exam);
			
			//添加成功后获取exam的id
			Integer examID = examDAO.getExamByTitle(exam.getTitle()).getId();
			
			//预处理examBanji信息
			examBanji.setExam(examID);
			examBanji.setCst_create(now);
			examBanji.setCst_modify(now);
			//预处理studentExam信息
			studentExam.setCst_create(now);
			studentExam.setCst_modify(now);
			studentExam.setExam(examID);
			studentExam.setStatus(1);
			studentExam.setHand_in_paper(0);
			for(int i=0; i<banji_array.length; i++){
				Integer banjiID = Integer.parseInt(banji_array[i]);
				examBanji.setBanji(banjiID);
				//添加examBanji信息
				examBanjiDAO.addNewExamBanji(examBanji);
				
				Integer studentID = null;
				List<Integer> studentIDList = studentDAO.getStudentIdByBanji(banjiID);
				Iterator iter = studentIDList.iterator();
				while(iter.hasNext()){
					studentID = (Integer) iter.next();
					studentExam.setStudent(studentID);
					//添加studentExam信息
					studentExamDAO.addNewStudentExam(studentExam);
				}
			}
			//这一段需要用事务！！！
			
			return true;
		} catch (Exception e) {
			model.put("error_exam", "考试添加失败，请检查内容后重试");
			return false;
		}
	}

	public boolean editUnstartExamInfo(Exam exam, Map model) {
		Exam dbExam = examDAO.getExamByTitle(exam.getTitle());
		if( dbExam == null || dbExam.getId().equals(exam.getId())){
			exam.setCst_modify(new Date());
			examDAO.updateUnstartExamInfo(exam);
			return true;
		}else{
			model.put("error_title", "该考试标题已经存在！");
            return false;
		}
	}

	public boolean editUnstartExamBanji(Integer examID, String[] banji_array, Map model){
		try{
			//这一段要用事务!!
			
			examBanjiDAO.deleteExamBanjiByExam(examID);
			studentExamDAO.deleteStudentExamByExam(examID);
			
			Date now = new Date();
			//预处理examBanji信息
			examBanji.setExam(examID);
			examBanji.setCst_create(now);
			examBanji.setCst_modify(now);
			//预处理studentExam信息
			studentExam.setCst_create(now);
			studentExam.setCst_modify(now);
			studentExam.setExam(examID);
			studentExam.setStatus(1);
			studentExam.setHand_in_paper(0);
			for(int i=0; i<banji_array.length; i++){
				Integer banjiID = Integer.parseInt(banji_array[i]);
				examBanji.setBanji(banjiID);
				//添加examBanji信息
				examBanjiDAO.addNewExamBanji(examBanji);
				
				Integer studentID = null;
				List<Integer> studentIDList = studentDAO.getStudentIdByBanji(banjiID);
				Iterator iter = studentIDList.iterator();
				while(iter.hasNext()){
					studentID = (Integer) iter.next();
					studentExam.setStudent(studentID);
					//添加studentExam信息
					studentExamDAO.addNewStudentExam(studentExam);
				}
			}
			
			//这一段要用事务!!
			return true;
		} catch (Exception e) {
			model.put("error_exam", "考试班级修改失败，请检查内容后重试");
			return false;
		}
	}

	/* 组卷核心方法之一
	 * 随机分配题型，1代表判断题，2代表选择题，3代表填空题
	 * 保存到一个数组中。
	 */
	private Integer[] allocation_type(Integer panduan_num, Integer xuanze_num, Integer tiankong_num){	
		//根据参数准备数据
		Integer question_num = panduan_num + xuanze_num + tiankong_num;	//题目的总数
		Integer[] question_type_array = new Integer[question_num];		//保存题型列表
		
		/*
		 * 设定判断题、选择题、填空题的类型编号依次为：1，2，3
		 * 将question_type_array数组的前panduan_num个元素赋值为1，
		 * 后xuanze_num个元素赋值为2，
		 * 最后tiankong_num个元素赋值为3.
		 */
		for(int i=0; i<question_num; i++){
			if( i < panduan_num ){
				question_type_array[i] = 1;
			}else if( i < (panduan_num+xuanze_num) ){
				question_type_array[i] = 2;
			}else if( i < (panduan_num+xuanze_num+tiankong_num) ){
				question_type_array[i] = 3;
			}
		}

		/*
		 * 将question_type_array中的元素随机打乱
		 */
		int random;
		int temp;
		for(int i=0; i<question_num; i++){
			random = (int) (question_num*Math.random());
			temp = question_type_array[random];
			question_type_array[random] = question_type_array[i];
			question_type_array[i] = temp;
		}
		return question_type_array;
	}
	
	/* 组卷核心方法之一
	 * 随机分配难度。要求：
	 * 1. 每道题的难度在1-9范围内；
	 * 2. 难度总和 = 总题数*平均难度；
	 */
	private Integer[] allocation_difficult(Integer panduan_num, Integer xuanze_num, Integer tiankong_num, Integer average_difficult){
		//根据参数准备数据
		Integer question_num = panduan_num + xuanze_num + tiankong_num;			//题目的总数
		Integer total_difficult = question_num*average_difficult;				//总难度
		Integer[] question_difficult_array = new Integer[question_num];			//保存难度列表
		
		//临时变量
		int left_question_num = question_num-1;		//在分配时保存后面还剩几题
		int left_difficult = total_difficult;		//在分配时保存剩余的难度值
		int min;		//保存随机数的下限；
		int max;		//保存随机数的上限；
		int random;		//保存随机数；
		for(int i=0; i<question_difficult_array.length; i++){
			/**
			 * 决定这次最少应该分配几分，否则即便后面的题目都取9分也满足不了总分。
			 * 下限是：(剩余的分数-剩下的题数*9) 和 1  中的最大值。
			 */
			min = Math.max(1, (left_difficult-left_question_num*9));
				
			/**
			 * 决定最多应该分配几分，否则即便后面的题目都取1分也会超过总分。
			 * 上限是：(剩余的分数-剩下的题数*1) 和 9  中的最小值。
			 */
			max = Math.min(9, (left_difficult-left_question_num*1));
			
			//生成随机数
			random = (int) ((max-min)*Math.random()+min);
			question_difficult_array[i] = random;
			left_difficult = left_difficult - random;
			left_question_num = left_question_num -1;
		}

		//不过这种算法会将数字大的放到最后，即最后几位可能都是9，所以需要将数组打乱。
		int temp;
		for(int i=0; i<question_num; i++){
			random = (int) (question_num*Math.random());
			temp = question_difficult_array[random];
			question_difficult_array[random] = question_difficult_array[i];
			question_difficult_array[i] = temp;
		}
		return question_difficult_array;
	}
	
	/* 组卷核心方法之一
	 * 处理覆盖率
	 */
	private Vector<Integer[]> allocation_coverage(Integer panduan_num, Integer xuanze_num, Integer tiankong_num, Integer total_score, Integer[] coverage_chapter, Integer[] coverage_percent){
		//根据参数准备数据
		Integer coverage_chapter_num = coverage_chapter.length;				//覆盖的章节的总数
		Integer question_num = panduan_num + xuanze_num + tiankong_num;		//题目的总数
		Integer[] cover_score = new Integer[coverage_chapter_num];			//保存每一章覆盖的分数
		Integer[] cover_question_num = new Integer[coverage_chapter_num];	//保存每一章覆盖的题数
		Integer[] question_chapter_array = new Integer[question_num];		//保存每一题所属的章节
		Integer[] question_score_array = new Integer[question_num];			//保存每一题的分数
		
		/*
		 * 根据百分比计算每一章覆盖的分数
		 * 为了避免出现小数的情况，前台限定总分和百分比的个位数必须为0.
		 */
		for(int i=0; i<coverage_chapter_num; i++){
			cover_score[i] = total_score*coverage_percent[i]/100;
		}
		
		/*
		 * 根据百分比计算每一章覆盖的题数
		 * 这个不需要十分精确。
		 * 为了避免出现小数的情况，可以前面几个取整，最后一个取剩。
		 */
		int left_question_num = question_num;
		for(int i=0; i<(coverage_chapter_num-1); i++){
			cover_question_num[i] = question_num*coverage_percent[i]/100;
			left_question_num = left_question_num - cover_question_num[i];
		}
		cover_question_num[coverage_chapter_num-1] = left_question_num;
		
		/*
		 * 按每一章覆盖的分数和每一章覆盖的题数给题目随机定分。
		 * 方法：
		 * 1. 给每题1分的基础分（防止出现分值为0的情况），
		 * 2. 从剩余的分数中拿出1分，随机指定该分数给某一题；
		 * 3. 再从剩余的分数中拿出1分，随机指定该分数给某一题；
		 * 4. 依次类推，直至剩余的分数变为0.
		 */
		int left_score;					//在分配时保存剩余的分数（在一章内）
		int random = 0;					//保存随机数；
		int chapter_question_num = 0;	//保存当前章节的题目数量；
		int index_bottom = 0;			//question_score_array下标的起始值（供每一章使用）
		for(int chapter=0; chapter<coverage_chapter_num; chapter++){
			//获取当前章节的题目数量
			chapter_question_num = cover_question_num[chapter];
			
			//给每题赋基础分1分
			for(int i=0; i<cover_question_num[chapter]; i++){
				question_score_array[index_bottom + i] = 1;
				
				/*
				 * 顺便给每题标上章节信息, 给question_chapter_array数组赋值，
				 * 由于题目的"难度"、"类型"和"分数"已经随机，所以"章节"只需（也需要）顺序保存。
				 * 约定前cover_question_num[i]题属于coverage_chapter[i]章，依次类推。
				 */
				question_chapter_array[index_bottom  + i] = coverage_chapter[chapter];
			}
			
			//计算剩余分值
			left_score = cover_score[chapter]-chapter_question_num;
			
			//分配剩余分值
			for(int i=0; i<left_score; i++){
				random = (int) (chapter_question_num*Math.random());
				++question_score_array[index_bottom + random];
			}
			
			//进入下一章节前调整下标的起始值
			index_bottom = index_bottom + chapter_question_num;
		}

		Vector<Integer[]> vec = new Vector<Integer[]>();
		vec.add(question_score_array);
		vec.add(question_chapter_array);
		
		return vec;
	}
	
	public boolean makeUpPaper(Paper paper, Integer examID, 
			Integer[] chapterArray, Integer[] percerntArray, Map model) {
		
		//获取组卷所需的因素
		Integer total_score = paper.getTotal_score();			//总分
		Integer average_difficult = paper.getDifficulty();		//平均难度
		Integer panduan_num = paper.getPanduan_num();			//判断题数目
		Integer xuanze_num = paper.getXuanze_num();				//选择题数目
		Integer tiankong_num = paper.getTiankong_num();			//填空题数目
		Integer[] coverage_chapter = chapterArray;				//覆盖率之覆盖的章节
		Integer[] coverage_percent = percerntArray;				//覆盖率之覆盖的百分比
		
		//核心数组
		Integer[] question_type_array = null;			//第一列：类型. 判断题、选择题、填空题的类型编号依次为：1，2，3
		Integer[] question_difficult_array = null;		//第二列：难度
		Integer[] question_score_array = null;			//第三列：分值
		Integer[] question_chapter_array = null;		//第四列：章节
		
		//保存题目的id序列
		String panduan_list = "";
		String xuanze_list = "";
		String tiankong_list = "";
		
		try {
			question_type_array = allocation_type(panduan_num, xuanze_num, tiankong_num);
			question_difficult_array = allocation_difficult(panduan_num, xuanze_num, tiankong_num, average_difficult);
			Vector<Integer[]> vec = allocation_coverage(panduan_num, xuanze_num, tiankong_num, total_score, coverage_chapter, coverage_percent);
			question_score_array = (Integer[]) vec.get(0);
			question_chapter_array = (Integer[]) vec.get(1);
		}catch (Exception e){
			model.put("error_param", "组卷参数存在异常，请检查后重试.");
			return false;
		}
		
		Integer question_num = panduan_num + xuanze_num + tiankong_num;
		boolean flag = true;
		int random = 0;
		int adjust = 0;		//最多尝试的次数;
		for( int i=0; i<question_num; i++){
			switch(question_type_array[i]){
			case 1:
				List<Panduan> panduanList = null;
				adjust = 0;
				while( adjust<9 ){
					//从数据库中提取题目
					panduanList = panduanDAO.getPanduanForPaper(Math.min(question_difficult_array[i]+adjust,9), question_score_array[i], question_chapter_array[i]);
					if( panduanList.isEmpty() != true ){
						break;		//如果取到题目了，则跳出循环；
					}else{
						adjust++;	//否则将难度加1，继续取;
					}
				}
				
				if(panduanList.isEmpty() == true || panduanList.size() == 0){
					//如果按上述参数提取不到，说明题库题量实在太少，组卷失败。
					flag = false;
				}else{
					//如果取到了，则从题目列表中随机提取一题，放入试卷中.
					random = (int) ((panduanList.size())*Math.random());
					panduan_list = panduan_list + panduanList.get(random).getId()+",";
				}
				break;
			case 2:
				List<Xuanze> xuanzeList = null;
				adjust = 0;
				while( adjust<9 ){
					//从数据库中提取题目
					xuanzeList = xuanzeDAO.getXuanzeForPaper(Math.min(question_difficult_array[i]+adjust,9), question_score_array[i], question_chapter_array[i]);
					if( xuanzeList.isEmpty() != true ){
						break;		//如果取到题目了，则跳出循环；
					}else{
						adjust++;	//否则将难度加1，继续取;
					}
				}
				
				if(xuanzeList.isEmpty() == true || xuanzeList.size() == 0){
					//如果按上述参数提取不到，说明题库题量实在太少，组卷失败。
					flag = false;
				}else{
					//如果取到了，则从题目列表中随机提取一题，放入试卷中.
					random = (int) ((xuanzeList.size())*Math.random());
					xuanze_list = xuanze_list + xuanzeList.get(random).getId()+",";
				}
				break;
			case 3:
				List<Tiankong> tiankongList = null;
				adjust = 0;
				while( adjust<9 ){
					//从数据库中提取题目
					tiankongList = tiankongDAO.getTiankongForPaper(Math.min(question_difficult_array[i]+adjust,9), question_score_array[i], question_chapter_array[i]);
					if( tiankongList.isEmpty() != true ){
						break;		//如果取到题目了，则跳出循环；
					}else{
						adjust++;	//否则将难度加1，继续取;
					}
				}
				
				if(tiankongList.isEmpty() == true || tiankongList.size() == 0){
					//如果按上述参数提取不到，说明题库题量实在太少，组卷失败。
					flag = false;
				}else{
					//如果取到了，则从题目列表中随机提取一题，放入试卷中.
					random = (int) ((tiankongList.size())*Math.random());
					tiankong_list = tiankong_list + tiankongList.get(random).getId()+",";
				}
				break;
			default:
				flag = false;
				break;
			}
			
			if(flag == false){
				model.put("error_param", "无法生成匹配的试卷，请更改参数后重试！或扩充题库!");
				return false;
			}
		}
		
		//组卷成功，完善试卷信息。
		Date now = new Date();
		paper.setCst_create(now);
		paper.setCst_modify(now);
		paper.setExam(examID);
		paper.setPanduan_list(panduan_list);
		paper.setXuanze_list(xuanze_list);
		paper.setTiankong_list(tiankong_list);
		paper.setZhuguan_list(null);		//附加题暂时没有。
		//将试卷信息写入数据库
		paperDAO.addPaperForExam(paper);
		examDAO.updatePaperForExam(examID, paperDAO.getPaperIdByExam(examID));
		
		return true;

	}

	public Paper gainPaper(Integer examID) {
		return paperDAO.getPaperByExam(examID);
	}

	public Integer checkPanduan(Integer panduanID, String panduan_answer_str, Integer studentID, Integer paperID) {
		//从数据库中取出题目
		Panduan panduan = panduanDAO.getPanduanById(panduanID);
		boolean flag = false;
		
		Integer panduan_answer = null;
		//检查答案是否正确
		if( panduan_answer_str == null || "".equals(panduan_answer_str)){
			flag = false;
		}else{
			panduan_answer = Integer.parseInt(panduan_answer_str);
			if( panduan_answer.equals(panduan.getCorrect_answer()) ){
				flag = true;
			}else{
				flag = false;
			}
		}
		
		if(!flag){
			//回答错误
			WrongPanduan wrongPanduan = new WrongPanduan();
			Date now = new Date();
			wrongPanduan.setCst_create(now);
			wrongPanduan.setCst_modify(now);
			wrongPanduan.setStudent(studentID);
			wrongPanduan.setPaper(paperID);
			wrongPanduan.setPanduan(panduanID);
			wrongPanduan.setWrong_answer(panduan_answer);
			//存入数据库
			wrongPanduanDAO.addWrongPanduan(wrongPanduan);
			
			return 0;
		}else{
			//回答正确
			return panduan.getScore();
		}

	}

	public Integer checkXuanze(Integer xuanzeID, String xuanze_answer, Integer studentID, Integer paperID) {
		//从数据库中取出题目
		Xuanze xuanze = xuanzeDAO.getXuanzeById(xuanzeID);
		boolean flag = false;
		
		//检查答案是否正确
		if( xuanze_answer == null || "".equals(xuanze_answer)){
			flag = false;
		}else{
			if( xuanze_answer.equals(xuanze.getCorrect_answer()) ){
				flag = true;
			}else{
				flag = false;
			}
		}
		
		if(!flag){
			//回答错误
			WrongXuanze wrongXuanze = new WrongXuanze();
			Date now = new Date();
			wrongXuanze.setCst_create(now);
			wrongXuanze.setCst_modify(now);
			wrongXuanze.setStudent(studentID);
			wrongXuanze.setPaper(paperID);
			wrongXuanze.setXuanze(xuanzeID);
			wrongXuanze.setWrong_answer(xuanze_answer);
			//存入数据库
			wrongXuanzeDAO.addWrongXuanze(wrongXuanze);
			
			return 0;
		}else{
			//回答正确
			return xuanze.getScore();
		}
	}

	public Integer checkTiankong(Integer tiankongID, String tiankong_answer, Integer studentID, Integer paperID) {
		//从数据库中取出题目
		Tiankong tiankong = tiankongDAO.getTiankongById(tiankongID);
		boolean flag = false;
		
		//检查答案是否正确
		if( tiankong_answer == null || "".equals(tiankong_answer)){
			flag = false;
		}else{
			//检查用户的答案是否与正确答案匹配.
			if( tiankong_answer.equals(tiankong.getCorrect_answer()) ){
				flag = true;
			}
			
			//检查用户的答案是否与近义词答案1匹配.
			if( (tiankong.getSynonym_one() != null) && tiankong_answer.equals(tiankong.getSynonym_one()) ){
				flag = true;
			}
			
			//检查用户的答案是否与近义词答案2匹配.
			if( (tiankong.getSynonym_two() != null) && tiankong_answer.equals(tiankong.getSynonym_two()) ){
				flag = true;
			}
			
			//检查用户的答案是否与近义词答案3匹配.
			if( (tiankong.getSynonym_three() != null) && tiankong_answer.equals(tiankong.getSynonym_three()) ){
				flag = true;
			}
		}
		
		if(!flag){
			//回答错误
			WrongTiankong wrongTiankong = new WrongTiankong();
			Date now = new Date();
			wrongTiankong.setCst_create(now);
			wrongTiankong.setCst_modify(now);
			wrongTiankong.setStudent(studentID);
			wrongTiankong.setPaper(paperID);
			wrongTiankong.setTiankong(tiankongID);
			wrongTiankong.setWrong_answer(tiankong_answer);
			//存入数据库
			wrongTiankongDAO.addWrongTiankong(wrongTiankong);
			
			return 0;
		}else{
			//回答正确
			return tiankong.getScore();
		}
	}
	
	public boolean addNewStudentPaper(StudentPaper studentPaper){
		try {
			studentPaperDAO.addNewStudentPaper(studentPaper);
			return true;
		} catch(Exception e){
			return false;
		}
	}

	public boolean editStudentExamForHandInPaper(StudentExam studentExam) {
		try{
			studentExamDAO.updateStudentExamForHandInPaper(studentExam);
			return true;
		}catch(Exception e){
			return false;
		}
	}

	public List<StudentExam> gainUnfinishedStudentExamForStudent(Integer studentID) {
		return studentExamDAO.getUnfinishedStudentExamForStudent(studentID);
	}
	
	public List<StudentExam> gainFinishedStudentExamForStudent(Integer studentID) {
		return studentExamDAO.getFinishedStudentExamForStudent(studentID);
	}
	
	public List<StudentExam> gainAbsentStudentExamForStudent(Integer studentID) {
		return studentExamDAO.getAbsentStudentExamForStudent(studentID);
	}
}
